package net.towee.client.gadgets;

import java.util.ArrayList;
import java.util.List;

import net.towee.client.com.app.Presenter;
import net.towee.client.managers.DashBoardManager;
import net.towee.model.account.Board;
import net.towee.model.account.Gadget;
import net.towee.model.group.GroupIdentity;
import net.towee.model.utils.Pair;

import com.google.common.base.Preconditions;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IsWidget;

/**
 * Abstract gadget presenter. Implements boiler plate methods and define base
 * Display interface.
 * 
 * @author c58
 */
public abstract class GadgetPresenter implements Presenter {

	public interface Display extends IsWidget {
		HasClickHandlers getCloseButton();

		HasClickHandlers getMinimizeButton();
		
		HasValueChangeHandlers<Pair<Integer, Integer>> getPositionChanger();
	}
	
	protected final Display display;
	protected final DashBoardManager boardManager;
	
	private Gadget gadget;
	private Board board;
	
	public GadgetPresenter(Display display, DashBoardManager boardManager){
		this.display = display;
		this.boardManager = boardManager;
		
		addHandlers();
	}

	private void addHandlers() {
		display.getCloseButton().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				removeGadgetFromBoard();
			}
		});
		
		display.getMinimizeButton().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				minimazeGadget();
			}
		});
		
		display.getPositionChanger().addValueChangeHandler(new ValueChangeHandler<Pair<Integer, Integer>>() {
			@Override
			public void onValueChange(ValueChangeEvent<Pair<Integer, Integer>> event) {
				changeGadgetPosition(event.getValue());
			}
		});
	}
	
	private void changeGadgetPosition(Pair<Integer, Integer> pair) {
		gadget.setRow( pair.getFirst() );
		gadget.setCel( pair.getSecond() );
		
		boardManager.saveGadget(board.getId(), gadget, new AsyncCallback<Boolean>(){
			@Override
			public void onFailure(Throwable caught) {	
			}

			@Override
			public void onSuccess(Boolean result) {
			}
		});
	}

	/**
	 * Minimize gadget
	 */
	private void minimazeGadget() {
		
	}

	/**
	 * Remove gadget from board
	 */
	private void removeGadgetFromBoard() {
		boardManager.detachGadgetFromBoard(board.getId(), gadget.getGadgetName(), new AsyncCallback<Boolean>() {
			@Override
			public void onFailure(Throwable caught) {	
			}

			@Override
			public void onSuccess(Boolean result) {		
			}
		});
	}

	public void setGadgetAndBoard(Gadget g, Board b) {
		this.gadget = g;
		this.board = b;
	}

	public Gadget getGadget() {
		return gadget;
	}
	
	public Board getBoard() {
		return board;
	}
	
	protected List<String> getAttachedGroups() {
		List<String> groups = new ArrayList<String>();
		
		for(GroupIdentity id : board.getAttachedGroups()) {
			groups.add( id.getId() );
		}
		
		return groups;
	}

	/**
	 * This implementation of go method check set of gadget data.
	 * Out side must set gadget data before invoking this method.
	 */
	@Override
	public void go(HasWidgets w) {
		Preconditions.checkNotNull(gadget, "gadget not set");
		showGadget(w);
	}

	/**
	 * Protected method for showing gadget
	 * @param container
	 */
	protected abstract void showGadget(HasWidgets container);
}
